﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace UniRx
{
	// Token: 0x02000205 RID: 517
	public abstract class StableCompositeDisposable : ICancelable, IDisposable
	{
		// Token: 0x06000C48 RID: 3144 RVA: 0x0003CF74 File Offset: 0x0003B374
		public static ICancelable Create(IDisposable disposable1, IDisposable disposable2)
		{
			if (disposable1 == null)
			{
				throw new ArgumentNullException("disposable1");
			}
			if (disposable2 == null)
			{
				throw new ArgumentNullException("disposable2");
			}
			return new StableCompositeDisposable.Binary(disposable1, disposable2);
		}

		// Token: 0x06000C49 RID: 3145 RVA: 0x0003CF9F File Offset: 0x0003B39F
		public static ICancelable Create(IDisposable disposable1, IDisposable disposable2, IDisposable disposable3)
		{
			if (disposable1 == null)
			{
				throw new ArgumentNullException("disposable1");
			}
			if (disposable2 == null)
			{
				throw new ArgumentNullException("disposable2");
			}
			if (disposable3 == null)
			{
				throw new ArgumentNullException("disposable3");
			}
			return new StableCompositeDisposable.Trinary(disposable1, disposable2, disposable3);
		}

		// Token: 0x06000C4A RID: 3146 RVA: 0x0003CFDC File Offset: 0x0003B3DC
		public static ICancelable Create(IDisposable disposable1, IDisposable disposable2, IDisposable disposable3, IDisposable disposable4)
		{
			if (disposable1 == null)
			{
				throw new ArgumentNullException("disposable1");
			}
			if (disposable2 == null)
			{
				throw new ArgumentNullException("disposable2");
			}
			if (disposable3 == null)
			{
				throw new ArgumentNullException("disposable3");
			}
			if (disposable4 == null)
			{
				throw new ArgumentNullException("disposable4");
			}
			return new StableCompositeDisposable.Quaternary(disposable1, disposable2, disposable3, disposable4);
		}

		// Token: 0x06000C4B RID: 3147 RVA: 0x0003D036 File Offset: 0x0003B436
		public static ICancelable Create(params IDisposable[] disposables)
		{
			if (disposables == null)
			{
				throw new ArgumentNullException("disposables");
			}
			return new StableCompositeDisposable.NAry(disposables);
		}

		// Token: 0x06000C4C RID: 3148 RVA: 0x0003D04F File Offset: 0x0003B44F
		public static ICancelable CreateUnsafe(IDisposable[] disposables)
		{
			return new StableCompositeDisposable.NAryUnsafe(disposables);
		}

		// Token: 0x06000C4D RID: 3149 RVA: 0x0003D057 File Offset: 0x0003B457
		public static ICancelable Create(IEnumerable<IDisposable> disposables)
		{
			if (disposables == null)
			{
				throw new ArgumentNullException("disposables");
			}
			return new StableCompositeDisposable.NAry(disposables);
		}

		// Token: 0x06000C4E RID: 3150
		public abstract void Dispose();

		// Token: 0x170000E5 RID: 229
		// (get) Token: 0x06000C4F RID: 3151
		public abstract bool IsDisposed { get; }

		// Token: 0x02000206 RID: 518
		private class Binary : StableCompositeDisposable
		{
			// Token: 0x06000C50 RID: 3152 RVA: 0x0003D070 File Offset: 0x0003B470
			public Binary(IDisposable disposable1, IDisposable disposable2)
			{
				this._disposable1 = disposable1;
				this._disposable2 = disposable2;
			}

			// Token: 0x170000E6 RID: 230
			// (get) Token: 0x06000C51 RID: 3153 RVA: 0x0003D091 File Offset: 0x0003B491
			public override bool IsDisposed
			{
				get
				{
					return this.disposedCallCount != -1;
				}
			}

			// Token: 0x06000C52 RID: 3154 RVA: 0x0003D09F File Offset: 0x0003B49F
			public override void Dispose()
			{
				if (Interlocked.Increment(ref this.disposedCallCount) == 0)
				{
					this._disposable1.Dispose();
					this._disposable2.Dispose();
				}
			}

			// Token: 0x0400070C RID: 1804
			private int disposedCallCount = -1;

			// Token: 0x0400070D RID: 1805
			private volatile IDisposable _disposable1;

			// Token: 0x0400070E RID: 1806
			private volatile IDisposable _disposable2;
		}

		// Token: 0x02000207 RID: 519
		private class Trinary : StableCompositeDisposable
		{
			// Token: 0x06000C53 RID: 3155 RVA: 0x0003D0CB File Offset: 0x0003B4CB
			public Trinary(IDisposable disposable1, IDisposable disposable2, IDisposable disposable3)
			{
				this._disposable1 = disposable1;
				this._disposable2 = disposable2;
				this._disposable3 = disposable3;
			}

			// Token: 0x170000E7 RID: 231
			// (get) Token: 0x06000C54 RID: 3156 RVA: 0x0003D0F5 File Offset: 0x0003B4F5
			public override bool IsDisposed
			{
				get
				{
					return this.disposedCallCount != -1;
				}
			}

			// Token: 0x06000C55 RID: 3157 RVA: 0x0003D103 File Offset: 0x0003B503
			public override void Dispose()
			{
				if (Interlocked.Increment(ref this.disposedCallCount) == 0)
				{
					this._disposable1.Dispose();
					this._disposable2.Dispose();
					this._disposable3.Dispose();
				}
			}

			// Token: 0x0400070F RID: 1807
			private int disposedCallCount = -1;

			// Token: 0x04000710 RID: 1808
			private volatile IDisposable _disposable1;

			// Token: 0x04000711 RID: 1809
			private volatile IDisposable _disposable2;

			// Token: 0x04000712 RID: 1810
			private volatile IDisposable _disposable3;
		}

		// Token: 0x02000208 RID: 520
		private class Quaternary : StableCompositeDisposable
		{
			// Token: 0x06000C56 RID: 3158 RVA: 0x0003D13C File Offset: 0x0003B53C
			public Quaternary(IDisposable disposable1, IDisposable disposable2, IDisposable disposable3, IDisposable disposable4)
			{
				this._disposable1 = disposable1;
				this._disposable2 = disposable2;
				this._disposable3 = disposable3;
				this._disposable4 = disposable4;
			}

			// Token: 0x170000E8 RID: 232
			// (get) Token: 0x06000C57 RID: 3159 RVA: 0x0003D170 File Offset: 0x0003B570
			public override bool IsDisposed
			{
				get
				{
					return this.disposedCallCount != -1;
				}
			}

			// Token: 0x06000C58 RID: 3160 RVA: 0x0003D180 File Offset: 0x0003B580
			public override void Dispose()
			{
				if (Interlocked.Increment(ref this.disposedCallCount) == 0)
				{
					this._disposable1.Dispose();
					this._disposable2.Dispose();
					this._disposable3.Dispose();
					this._disposable4.Dispose();
				}
			}

			// Token: 0x04000713 RID: 1811
			private int disposedCallCount = -1;

			// Token: 0x04000714 RID: 1812
			private volatile IDisposable _disposable1;

			// Token: 0x04000715 RID: 1813
			private volatile IDisposable _disposable2;

			// Token: 0x04000716 RID: 1814
			private volatile IDisposable _disposable3;

			// Token: 0x04000717 RID: 1815
			private volatile IDisposable _disposable4;
		}

		// Token: 0x02000209 RID: 521
		private class NAry : StableCompositeDisposable
		{
			

			// Token: 0x06000C5A RID: 3162 RVA: 0x0003D1DA File Offset: 0x0003B5DA
			public NAry(IEnumerable<IDisposable> disposables)
			{
				this._disposables = new List<IDisposable>(disposables);
				if (this._disposables.Contains(null))
				{
					throw new ArgumentException("Disposables can't contains null", "disposables");
				}
			}

			// Token: 0x170000E9 RID: 233
			// (get) Token: 0x06000C5B RID: 3163 RVA: 0x0003D21A File Offset: 0x0003B61A
			public override bool IsDisposed
			{
				get
				{
					return this.disposedCallCount != -1;
				}
			}

			// Token: 0x06000C5C RID: 3164 RVA: 0x0003D228 File Offset: 0x0003B628
			public override void Dispose()
			{
				if (Interlocked.Increment(ref this.disposedCallCount) == 0)
				{
					foreach (IDisposable disposable in this._disposables)
					{
						disposable.Dispose();
					}
				}
			}

			// Token: 0x04000718 RID: 1816
			private int disposedCallCount = -1;

			// Token: 0x04000719 RID: 1817
			private volatile List<IDisposable> _disposables;
		}

		// Token: 0x0200020A RID: 522
		private class NAryUnsafe : StableCompositeDisposable
		{
			// Token: 0x06000C5D RID: 3165 RVA: 0x0003D298 File Offset: 0x0003B698
			public NAryUnsafe(IDisposable[] disposables)
			{
				this._disposables = disposables;
			}

			// Token: 0x170000EA RID: 234
			// (get) Token: 0x06000C5E RID: 3166 RVA: 0x0003D2B0 File Offset: 0x0003B6B0
			public override bool IsDisposed
			{
				get
				{
					return this.disposedCallCount != -1;
				}
			}

			// Token: 0x06000C5F RID: 3167 RVA: 0x0003D2C0 File Offset: 0x0003B6C0
			public override void Dispose()
			{
				if (Interlocked.Increment(ref this.disposedCallCount) == 0)
				{
					int num = this._disposables.Length;
					for (int i = 0; i < num; i++)
					{
						this._disposables[i].Dispose();
					}
				}
			}

			// Token: 0x0400071A RID: 1818
			private int disposedCallCount = -1;

			// Token: 0x0400071B RID: 1819
			private volatile IDisposable[] _disposables;
		}
	}
}
